#pragma once
#ifndef H_CHARACTERFACTORY
#define H_CHARACTERFACTORY
#include "precompiled.h"
namespace weo
{
    namespace engine
    {
        namespace character
        {
            class CharacterFactory
            {
            private:
                typedef void * (CharacterFactoryFn) ();
                std::map<std::string,std::map<std::string,CharacterFactoryFn*>> m_ClassBuildMap;
                // <<singleton>>
                static CharacterFactory* s_Factory;
            public:
                template<typename ClassName>
                static ClassName *CallFactory(std::string classname, std::string buildname)
                {
                    return (ClassName *)getInstance()->callFactory(classname, buildname);
                }
                static void RegisterClassBuild(std::string classname, std::string buildname, CharacterFactoryFn* pFunction)
                {
                    getInstance()->registerClassBuild(classname,buildname,pFunction);
                }
                static CharacterFactory* getInstance();
                void* callFactory(std::string classname, std::string buildname);
                void registerClassBuild(std::string classname, std::string buildname, CharacterFactoryFn* pFunction);
                template<typename ClassName>
                static void* FactoryFunction()
                {
                    return new ClassName;
                }
                std::vector<std::string> getClasses()
                {
                    std::vector<std::string> retval;
                    std::map<std::string,std::map<std::string,CharacterFactoryFn*>>::iterator it;
                    for(it=m_ClassBuildMap.begin();it!=m_ClassBuildMap.end();it++)
                    {
                        retval.push_back(it->first);
                    }
                    return retval;
                }
                std::vector<std::string> getBuilds(const std::string& classname)
                {
                    std::vector<std::string> retval;
                    std::map<std::string,std::map<std::string,CharacterFactoryFn*>>::iterator it = m_ClassBuildMap.find(classname);
                    if(it != m_ClassBuildMap.end())
                    {
                        std::map<std::string,CharacterFactoryFn*>::iterator it2;
                        for(it2 = it->second.begin();it2 != it->second.end();it2++)
                        {
                            retval.push_back(it2->first);
                        }						
                    }
                    return retval;
                }
                static std::vector<std::string> GetClasses()
                {
                    return getInstance()->getClasses();
                }
                static std::vector<std::string> GetBuilds(const std::string& value)
                {
                    return getInstance()->getBuilds(value);
                }
            };
        };
    };
};
#endif